package com.apes.fn.scm.dumpComm.service;

import com.apes.scm.masterdata.enumeration.model.BusinessParam;
import com.apes.scm.masterdata.enumeration.repository.BusinessParamRepository;
import com.apes.fn.scm.crossCompany.transfer.repository.TransferProductRepository;
import com.apes.fn.scm.dumpComm.model.DumpOperation;
import com.apes.fn.scm.dumpComm.model.PublicParam;
import com.apes.framework.api.DomainService;
import com.apes.framework.api.SpringManager;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.framework.plugin.cache.MemoryCache;
import com.apes.framework.util.DateUtil;
import com.apes.framework.util.MapUtil;
import com.apes.scm.account.account.repository.StockRepository;
import com.apes.scm.contract.repository.ContractRepository;
import com.apes.scm.masterdata.enumeration.model.Enumeration;
import com.apes.scm.masterdata.enumeration.repository.EnumerationRepository;
import com.apes.scm.masterdata.frame.service.StoreService;
import com.apes.scm.masterdata.party.model.PartyRole;
import com.apes.scm.masterdata.party.repository.PartyRoleRepository;
import com.apes.scm.masterdata.product.model.Product;
import com.apes.scm.masterdata.product.model.ProductUom;
import com.apes.scm.masterdata.product.repository.ProductRepository;
import com.apes.scm.masterdata.product.repository.ProductUomRepository;
import com.apes.scm.masterdata.stock.model.Location;
import com.apes.scm.rbac.model.User;
import com.apes.scm.rbac.repository.UserRepository;
import com.apes.scm.stock.safetyStock.repository.SafetyStockGapRepository;
import com.apes.scm.stock.transfer.model.Transfer;
import com.apes.scm.stock.transfer.repository.TransferRepository;
import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

@Service("safetyGapOperationService")
public class SafetyGapOperationService extends DomainService implements DumpOperation{

    @Autowired
    private EnumerationRepository enumerationRepository;
    @Autowired
    private SafetyStockGapRepository safetyStockGapRepository;
    @Autowired
    private ProductUomRepository productUomRepository;
    @Autowired
    private StoreService storeService;
    @Autowired
    private StockRepository stockRepository;
    @Autowired
    private ProductRepository productRepository;
    @Autowired
    private PartyRoleRepository partyRoleRepository;
    @Autowired
    private TransferRepository transferRepository;
    @Autowired
    private TransactionTemplate transactionTemplate;
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private BusinessParamRepository businessParamRepository;
    @Autowired
    private TransferProductRepository transferProductRepository;

    private final String SAFETY_GAP_TRANSFER_PRODUCT_CACHE = "initSafetyGapTransferProduct";

    private MemoryCache memoryCache = MemoryCache.getInstance();

    @Override
    public void initData() {
        Map transferProduct = (Map) memoryCache.get(SAFETY_GAP_TRANSFER_PRODUCT_CACHE);
        if (transferProduct != null && !transferProduct.isEmpty()) return;

        List directlySuppliers = new ArrayList();
        List noDirectorySuppliers = new ArrayList();
        List empowermentToDirectlySuppliers = new ArrayList();
        List empowermentToSubSuppliers = new ArrayList();
        boolean directlyExistsSupplierNull = false; // 直营供应商为空
        boolean noDirectlyExistsSupplierNull = false; // 非直营供应商为空
        boolean empowermentToDirectlySupplierNull = false; // 赋能 - 直营 供应商为空
        boolean empowermentToSubSupplierNull = false; // 赋能 - 子公司 供应商为空

        // 直营 ---> 非直营
        List<Map> findExportToNoExportSuppliers = invoke("scm.transferProductService.findExportToDirectly", null);
        Map supplierIsnull = findExportToNoExportSuppliers.stream().filter(filterSupplier -> {return StringUtils.isEmpty((filterSupplier).get("SUPPLIER_ID"));}).findAny().orElse(new HashMap());
        directlyExistsSupplierNull = !supplierIsnull.isEmpty();
        if (!directlyExistsSupplierNull) {
            directlySuppliers = findExportToNoExportSuppliers.stream().map(supplier -> (supplier).get("SUPPLIER_ID")).collect(Collectors.toList());
        }

        // 调出方 赋能 -- 赋能
//        List<Map> findExportNoDirecltyToAlls = invoke("scm.transferProductService.findExportNoDirectlyToAll", MapUtil.mapper("export", "001073"))
        List<Map> findExportNoDirecltyToAlls = transferProductRepository.findByALLTwo("001073", "001073");
        supplierIsnull = findExportNoDirecltyToAlls.stream().filter(filterSupplier -> {return StringUtils.isEmpty((filterSupplier).get("SUPPLIER_ID"));}).findAny().orElse(new HashMap());
        noDirectlyExistsSupplierNull = !supplierIsnull.isEmpty();
        if (!noDirectlyExistsSupplierNull) {
            noDirectorySuppliers = findExportNoDirecltyToAlls.stream().map(supplier -> (supplier).get("SUPPLIER_ID")).collect(Collectors.toList());
            List<Map> vaildContracts = SpringManager.getBean(ContractRepository.class).stockGapDumpFindContract(noDirectorySuppliers);
            noDirectorySuppliers = vaildContracts.stream().map(vaildSupplier -> (vaildSupplier).get("PARTNER_ID")).collect(Collectors.toList());
        }

        // 调出方 赋能 -- 直营
        findExportNoDirecltyToAlls = transferProductRepository.findByALLTwo("001073", "001072");
        supplierIsnull = findExportNoDirecltyToAlls.stream().filter(filterSupplier -> {return StringUtils.isEmpty((filterSupplier).get("SUPPLIER_ID"));}).findAny().orElse(new HashMap());
        empowermentToDirectlySupplierNull = !supplierIsnull.isEmpty();
        if (!empowermentToDirectlySupplierNull) {
            empowermentToDirectlySuppliers = findExportNoDirecltyToAlls.stream().map(supplier -> (supplier).get("SUPPLIER_ID")).collect(Collectors.toList());
            List<Map> vaildContracts = SpringManager.getBean(ContractRepository.class).stockGapDumpFindContract(empowermentToDirectlySuppliers);
            empowermentToDirectlySuppliers = vaildContracts.stream().map(vaildSupplier -> (vaildSupplier).get("PARTNER_ID")).collect(Collectors.toList());
        }

        // 调出方 赋能 -- 子公司
        findExportNoDirecltyToAlls = transferProductRepository.findByALLTwo("001073", "001661");
        supplierIsnull = findExportNoDirecltyToAlls.stream().filter(filterSupplier -> {return StringUtils.isEmpty((filterSupplier).get("SUPPLIER_ID"));}).findAny().orElse(new HashMap());
        empowermentToSubSupplierNull = !supplierIsnull.isEmpty();
        if (!empowermentToSubSupplierNull) {
            empowermentToSubSuppliers = findExportNoDirecltyToAlls.stream().map(supplier -> (supplier).get("SUPPLIER_ID")).collect(Collectors.toList());
            List<Map> vaildContracts = SpringManager.getBean(ContractRepository.class).stockGapDumpFindContract(empowermentToDirectlySuppliers);
            empowermentToSubSuppliers = vaildContracts.stream().map(vaildSupplier -> (vaildSupplier).get("PARTNER_ID")).collect(Collectors.toList());
        }

        memoryCache.put(SAFETY_GAP_TRANSFER_PRODUCT_CACHE,
                MapUtil.mapper("directlySuppliers", directlySuppliers,
                        "directlyExistsSupplierNull", directlyExistsSupplierNull,
                        "noDirectorySuppliers", noDirectorySuppliers,
                        "noDirectlyExistsSupplierNull", noDirectlyExistsSupplierNull,
                        "empowermentToDirectlySuppliers", empowermentToDirectlySuppliers,
                        "empowermentToDirectlySupplierNull", empowermentToDirectlySupplierNull,
                        "empowermentToSubSupplierNull", empowermentToSubSupplierNull,
                        "empowermentToSubSuppliers", empowermentToSubSuppliers));
    }

    @Override
    public boolean executeBeforeOperation(PublicParam publicParam) {
        // 晚上 19点 后才开始执行
        BusinessParam businessParam = businessParamRepository.findAllByQueryKey("safetyGapTime").get(0);
        int startRunTime = Integer.valueOf(businessParam.getValue());
        if (this.dataHour() < startRunTime || this.dataHour() == 24 || this.dataHour() == 0) return false;
        if (this.dataHour() == 23 && this.dataMinute() < 59 && this.dataMinute() > 50)  return false; // 数据需要在 凌晨 之前的时间段跑出来

        // 获取仓库级别
        Enumeration storeLevels = this.findStoreLevel(/*publicParam*/);
        if (("000121".equals(publicParam.getDevelId())) || ("000121".equals(storeLevels.getId()) && memoryCache.get(SAFETY_GAP_TRANSFER_PRODUCT_CACHE) == null)) {
            PublicParam.getInstance("000121");
            memoryCache.remove(SAFETY_GAP_TRANSFER_PRODUCT_CACHE);
            return false; // 表示所有仓库都执行完毕
        } else {
            publicParam.setDevelId(storeLevels.getId());
        }
        return true;
    }

    @Override
    public boolean underImplementationOperation(Location fLocation, Location cLocation) {
        // 获取发货仓的收货仓范围
        List canDumpReceiptLocations = invoke("cross.crossCompanyTransferNewService.externalCanDumpReceiptLocation", MapUtil.mapper("id", fLocation.getId()));
        if (!canDumpReceiptLocations.contains(cLocation.getId())) {
            this.sendStockGapDistributionInfo(fLocation, cLocation);
            return false;
        }

        // 是否封库
        if (storeService.judgeFCKBJFlag(fLocation) || storeService.judgeFCKBJFlag(cLocation)) {
            this.sendStockGapDistributionInfo(fLocation, cLocation);
            return false;
        }
        return true;
    }


    @Override
    public void executeAfterOperation(Location fLocation, Location cLocation) {
        this.sendStockGapDistributionInfo(fLocation, cLocation);
    }

    @Override
    public void sendDump(int prePage, int nextPage, boolean isNotCross, PublicParam publicParam) {
        Set<Map> dumpItems = new HashSet<>();
        List<Map> gapLocationProducts = safetyStockGapRepository.qrySafetyStockGapItemPage(publicParam.getClocation().getId(), prePage, nextPage);
        gapLocationProducts.forEach(gapProduct -> {
            String productId = gapProduct.get("PRODUCT_ID").toString();
            double totalQty = Double.parseDouble(gapProduct.get("TOTAL_QTY").toString());
            double assignedQty = Double.parseDouble(gapProduct.get("ASSIGNED_QTY").toString());
            double rabbetQty = totalQty - assignedQty;

            ProductUom minUom = productUomRepository.findAll(JpaDsl.toCriteriaByEq("uomCategory.id", productId, "factor", 1)).get(0);
            publicParam.setProductCache(productId);
            publicParam.setMinFactorUom(minUom);
            publicParam.setStatisticsDate(gapProduct.get("STATISTICS_DATE_CHAR").toString());

            // 获取库存数量等信息
            Map dumpItemData = this.gapQtyCompare(publicParam, rabbetQty);
            if (dumpItemData == null || dumpItemData.isEmpty()) return;
            dumpItemData.put("id", gapProduct.get("ID").toString());

            // 拼接调拨、转储明细
            Map dumpItemM = this.appendDumpItem(isNotCross, productId, dumpItemData);
            dumpItems.add(dumpItemM);
        });

        // 拼接转储、调拨主表
        Map dumpData = this.appendDumpMain(isNotCross, dumpItems, publicParam);

        // 发送转储、调拨请求
        this.sendSaveDuampRequest(dumpData, isNotCross);
    }

    // 缺口数量对比
    private Map gapQtyCompare(PublicParam publicParam, double rabbetQty) {
        ProductUom dumpUom = productUomRepository.findAll(JpaDsl.toCriteriaByEq("uomCategory.id", publicParam.getProduct().getId(), "transferFirst", true)).get(0);
        double newRabbet = this.changeQty(publicParam.getMinFactorUom(), dumpUom, rabbetQty); // 缺口数量

        // 获取库存
        Map allStocks = this.findStocks(publicParam);
        if (allStocks.isEmpty()) {
            this.writeRequireMongoLog(MapUtil.mapper("productId", publicParam.getProduct().getId(), "fLocationId", publicParam.getFlocation().getId(), "cLocationId", publicParam.getClocation().getId(), "rabbetQty", rabbetQty, "content", "无库存"));
            return null;
        }

        // 获取可用数
        double usableQty = Double.parseDouble(allStocks.get("USABLE_QTY").toString());
        double newUsableQty = this.changeQtyFloor(publicParam.getMinFactorUom(), dumpUom, usableQty);
        if (newRabbet <= 0 || newUsableQty <= 0) {
            this.writeRequireMongoLog(MapUtil.mapper("productId", publicParam.getProduct().getId(), "fLocationId", publicParam.getFlocation().getId(), "cLocationId", publicParam.getClocation().getId(),
                    "rabbetQty", rabbetQty, "newRabbet", newRabbet, "newUsableQty", newUsableQty));
            return null;
        }

        double dumpQty = newRabbet > newUsableQty?newUsableQty:newRabbet;
        return MapUtil.mapper("dumpUom", dumpUom, "dumpQty", dumpQty, "newUsableQty", newUsableQty);
    }

    // 数量转换
    private double changeQty(ProductUom minFactorUom, ProductUom nonMiniUom, double qty) {
        return Math.ceil(minFactorUom.computeQty(qty, nonMiniUom, false));
    }

    private double changeQtyFloor(ProductUom minFactorUom, ProductUom nonMiniUom, double qty) {
        return Math.floor(minFactorUom.computeQty(qty, nonMiniUom, false));
    }



    // 查找库存
    private Map findStocks(PublicParam publicParam) {
        Map transferProductCache = (Map) memoryCache.get(SAFETY_GAP_TRANSFER_PRODUCT_CACHE);
        if ("001073".equals(publicParam.getExport()) && "001072".equals(publicParam.getReception())) {
            if (!(boolean) transferProductCache.get("empowermentToDirectlySupplierNull")) { // 赋能 - 直营
                return stockRepository.availableStockSupplierContract(publicParam.getFlocation().getId(), publicParam.getProduct().getId(), (List) transferProductCache.get("empowermentToDirectlySuppliers"));
            } else {
                return stockRepository.availableStockAllSupplierContract(publicParam.getFlocation().getId(), publicParam.getProduct().getId());
            }
        } else if ("001073".equals(publicParam.getExport()) && "001661".equals(publicParam.getReception())) { // 赋能 -子公司
            if (!(boolean) transferProductCache.get("empowermentToSubSupplierNull")) {
                return stockRepository.availableStockSupplierContract(publicParam.getFlocation().getId(), publicParam.getProduct().getId(), (List) transferProductCache.get("empowermentToSubSuppliers"));
            } else {
                return stockRepository.availableStockAllSupplierContract(publicParam.getFlocation().getId(), publicParam.getProduct().getId());
            }

        } else if ("001073".equals(publicParam.getExport()) && "001073".equals(publicParam.getReception())) { // 赋能 - 赋能
            if (!(boolean) transferProductCache.get("noDirectlyExistsSupplierNull")) {
                return stockRepository.availableStockSupplierContract2(publicParam.getFlocation().getId(), publicParam.getProduct().getId(), (List) transferProductCache.get("noDirectorySuppliers"));
            } else {
                return stockRepository.availableStockAllSupplierContract(publicParam.getFlocation().getId(), publicParam.getProduct().getId());
            }
        } else {
            if (!(boolean) transferProductCache.get("directlyExistsSupplierNull")) {
                return stockRepository.availableStockSupplier(publicParam.getFlocation().getId(), publicParam.getProduct().getId(), (List) transferProductCache.get("directlySuppliers"));
            } else {
                return stockRepository.availableStockAllSupplier(publicParam.getFlocation().getId(), publicParam.getProduct().getId());
            }
        }
    }

    // 写入 mongo 日志
    public void writeRequireMongoLog(Map param) {
        Document column = new Document();
        column.putAll(param);
        column.put("currentDate", DateUtil.format(new Date(), DateUtil.SHOW_DATE_FORMAT));
        mongoTemplate.getCollection("autoSafetyStockLog").insertOne(column);
    }


    // 新增缺口执行数据
    private void sendStockGapDistributionInfo(Location fcLocationInfo, Location cLocationInfo) {
        try {
            invoke("stock.stockGapDistributionInfoService.create",
                    MapUtil.mapper("FLocation", MapUtil.mapper("id", fcLocationInfo.getId()), "location",  MapUtil.mapper("id", cLocationInfo.getId())));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 获取仓库级别
    private Enumeration findStoreLevel(/*PublicParam publicParam*/) {
        // 有仓库缺口时，根据仓库缺口获取仓库级别
        List getGaps = safetyStockGapRepository.existsExecuData(/*publicParam.getDevelId()*/);
        if (!getGaps.isEmpty()) {
            return enumerationRepository.findOne(((Map) getGaps.get(0)).get("DEPOT_LEVEL").toString());
        }

        // 无缺口时，获取缺口表是否还有未完成的仓库，获取未完成仓库的级别
        List<Enumeration> tempLocationLevels = new ArrayList<>();
        List depotLevels = safetyStockGapRepository.findStoreLevels();
        if (depotLevels.isEmpty()) {
            Sort sort = new Sort(Sort.Direction.DESC, "code");
            tempLocationLevels = enumerationRepository.findAll(JpaDsl.toCriteriaByEq("type.id", "depotLevel"), sort);
        } else {
            tempLocationLevels = enumerationRepository.findDepotLevels("depotLevel", (List) depotLevels.stream().map(singleLevel -> ((Map) singleLevel).get("DEPOT_LEVEL")).collect(Collectors.toList()));
        }

        Enumeration enumeration = tempLocationLevels.size() > 1?tempLocationLevels.get(0):tempLocationLevels.get(0);
        return enumeration;
    }

    // 发送转储请求
    private void sendSaveDuampRequest(Map dumpData, boolean isNotCross) {
        if (dumpData == null || dumpData.isEmpty()) return;
        if (!isNotCross) {
            invoke("cross.crossCompanyTransferNewService.safetyGapCreateCross", dumpData); // 需要考虑报错写入日志????????????????????????
        } else {
            Transfer transfer = invoke("stock.transfer.autoRequireTransfer", dumpData);
            transfer = transferRepository.findOne(transfer.getId());
            transfer.setApproveUid(transfer.getCreateUid());
            invoke("stock.transfer.approve", transfer);
        }
    }

    public void execute(Callback callback) {
        transactionTemplate.execute(status -> {
            try {
                callback.execute();
                return null;
            } catch (Exception e) {
                status.isRollbackOnly();
                throw e;
            }
        });
    }

    @FunctionalInterface
    public interface Callback {
        @Nullable
        void execute();
    }

    private int dataHour() {
        String date = DateUtil.format(new Date(), DateUtil.SHOW_TIME_FORMAT);
        return Integer.valueOf(date.substring(0, 2));
    }

    private int dataMinute() {
        String date = DateUtil.format(new Date(), DateUtil.SHOW_TIME_FORMAT);
        return Integer.valueOf(date.substring(3, 5));
    }

    // 拼接转储主表数据
    private Map appendDumpMain(boolean isNotCross, Set<Map> dumpItems, PublicParam publicParam) {
        if (dumpItems == null || dumpItems.isEmpty()) return new HashMap();
        if (isNotCross) {
            return appendTransferData(publicParam.getFlocation(), publicParam.getClocation(), dumpItems, publicParam.getStatisticsDate());
        } else {
            return appendCrossMain(dumpItems, publicParam);
        }
    }

    // 拼接转储主表
    private Map appendTransferData(Location fLocation, Location cLocation, Set<Map> transferItems, String statisticsDate) {
        Map transfer = new HashMap();
        PartyRole operatorName = SpringManager.getBean(PartyRoleRepository.class).findOne("system");
        List<User> userInfo = SpringManager.getBean(UserRepository.class).findAll(JpaDsl.toCriteriaByEq("person.id", operatorName.getId()));
        transfer.put("creator", operatorName.getId());
        transfer.put("createUid", MapUtil.mapper("id", operatorName.getId(), "name", operatorName.getName()));
        transfer.put("userId", userInfo.get(0).getId());
        transfer.put("transferItems", transferItems);
        transfer.put("specialDocuments", statisticsDate);
        transfer.put("specialDocumentsType", "SafetyStockGap");
        transfer.put("scene", MapUtil.mapper("id", "PT001"));
        transfer.put("originLocation", MapUtil.mapper("id", fLocation.getId(), "name", fLocation.getName()));
        transfer.put("receiptLocation", MapUtil.mapper("id", cLocation.getId(), "name", cLocation.getName()));
        transfer.put("company", MapUtil.mapper("id", cLocation.getCompany().getId()/*, "name", cLocation.getCompany().getName()*/));
        transfer.put("note", "安全库存自动补货");
        transfer.put("reason", MapUtil.mapper("id", "000180"));
        transfer.put("state", "sent");
        transfer.put("transferType", MapUtil.mapper("id", "000165"));
        return transfer;
    }

    // 拼接跨公司主数据
    private Map appendCrossMain(Set<Map> crossItems, PublicParam publicParam) {
        PartyRole operator = partyRoleRepository.findOne("system");
        Map crossTransferItem = new HashMap();
        crossTransferItem.put("creator", operator.getId());
        crossTransferItem.put("createUid", MapUtil.mapper("id", operator.getId(), "name", operator.getName()));
        crossTransferItem.put("crossCompanyTransferItems", crossItems);
        crossTransferItem.put("specialDocuments", publicParam.getStatisticsDate());
        crossTransferItem.put("specialDocumentsType", "SafetyStockGap");
        crossTransferItem.put("company", MapUtil.mapper("id", publicParam.getClocation().getCompany().getId()/*, "name", publicParam.getClocation().getCompany().getName()*/));
        crossTransferItem.put("shipLocation", MapUtil.mapper("id", publicParam.getFlocation().getId()/*, "name", publicParam.getFlocation().getName()*/));
        crossTransferItem.put("receiptLocation", MapUtil.mapper("id", publicParam.getClocation().getId()/*, "name", publicParam.getClocation().getName()*/));
        crossTransferItem.put("returnReason", MapUtil.mapper("id", "000180"));
        crossTransferItem.put("state", "sent");
        crossTransferItem.put("note", "安全库存自动补货");
        crossTransferItem.put("isAuto", true);

        Map transferProductCache = (Map) memoryCache.get(SAFETY_GAP_TRANSFER_PRODUCT_CACHE);
        if ("001073".equals(publicParam.getExport()) && "001072".equals(publicParam.getReception())) { // 暂时不考虑子公司
            crossTransferItem.put("existsTransferProductSupplierIsNull", transferProductCache.get("empowermentToDirectlySupplierNull"));
            crossTransferItem.put("transferProductSuppliers", transferProductCache.get("empowermentToDirectlySuppliers"));
            crossTransferItem.put("empowermentToNoEmpowerment", true);
        } else if ("001073".equals(publicParam.getExport()) && "001073".equals(publicParam.getReception())) {
            crossTransferItem.put("existsTransferProductSupplierIsNull", transferProductCache.get("noDirectlyExistsSupplierNull"));
            crossTransferItem.put("transferProductSuppliers", transferProductCache.get("noDirectorySuppliers"));
        } else {
            crossTransferItem.put("existsTransferProductSupplierIsNull", transferProductCache.get("directlyExistsSupplierNull"));
            crossTransferItem.put("transferProductSuppliers", transferProductCache.get("directlySuppliers"));
        }

        return crossTransferItem;
    }

    // 拼接转储明细
    private Map appendDumpItem(boolean isNotCross, String productId, Map dumpParam) {
        Product product = productRepository.findOne(productId);
        if (isNotCross) {
            return this.appendTransferItem(product, dumpParam);
        } else {
            return this.appendCrossCompanyTransferItem(product, dumpParam);
        }

    }

    /** 拼接转储订单明细 */
    private Map appendTransferItem(Product product, Map dumpParam) {
        ProductUom dumpUom = (ProductUom) dumpParam.get("dumpUom");
        double dumpQty = (double) dumpParam.get("dumpQty");
        return MapUtil.mapper("product", MapUtil.mapper("id", product.getId()), "uom", MapUtil.mapper("id", dumpUom.getId()), "transferQty", dumpQty, "originItemId", dumpParam.get("id"));
    }

    /** 拼接跨公司调拨明细 */
    private Map appendCrossCompanyTransferItem(Product product, Map dumpParam) {
        ProductUom dumpUom = (ProductUom) dumpParam.get("dumpUom");
        double dumpQty = (double) dumpParam.get("dumpQty");
        double newUsableQty = (double) dumpParam.get("newUsableQty");
        return MapUtil.mapper("product", MapUtil.mapper("id", product.getId()), "uom", MapUtil.mapper("id", dumpUom.getId()),
                "productSumQty", newUsableQty, "productSum", dumpQty, "originItemId", dumpParam.get("id"));
    }
}
